package lineanalysis

import (
	"codejy/analysis"
	"codejy/globalfunc"
	"codejy/structdef"
)

func init() {
	globalfunc.RegisterFuncAll("LineAnalysisAll", LineAnalysisAll)
	globalfunc.RegisterFuncAll("LineAnalysisTypeAndFun", LineAnalysisTypeAndFun)
	globalfunc.RegisterFuncAll("CmdLineAnalysis", CmdLineAnalysis)

}

const (
	//变量定义
	VariableDefinition = iota
	//赋值语句
	Assignment
	TypeAssignment
	//函数定义
	FunctionDefine
	//匿名函数定义
	AnonymousFunctionDefine
	//函数调用
	FunctionCall
	//多级函数调用
	FunctionCallMulti
	//类型定义
	TypeDefine
	//延迟执行
	Defer
	//if语句
	If
	//switch语句
	Switch
	//for语句
	For
	//to语句
	To
	//break语句
	Break
	//continue语句
	Continue
	//类型行为定义
	DEF
	//自增自减
	IncrementDecrement
	//实例化
	InstanceCreate
	//结束程序运行
	EXIT
	//抛出错误
	Throw

	//实例地址调用方法
	InstanceAddressMethod
	//实例调用方法
	InstanceMethod
	//全局文件方法调用
	GlobalMethod
	//this.调用方法
	ThisMethod
	//调用其他文件的方法
	CrossFileDefineMethod
	//核心方法
	CoreFun
	//多行字符串
	MultiLineString
	//全局变量赋值
	GlobalPropAssignment
	//实例变量赋值
	InstancePropAssignment
	//实例地址变量赋值
	InstanceAddressPropAssignment
	//this变量赋值
	ThisPropAssignment
	//连续调用
	UniteCallChain
	//连续调用赋值
	UniteCallChainAssignment
)

func LineAnalysisAll(threadStore *structdef.ThreadStore, codeLine string) int {
	//判断是多行字符串
	if analysis.IsMultiLineString(codeLine) {
		return MultiLineString
	}
	//判断是否是延迟执行
	if analysis.IsDefer(codeLine) {
		return Defer
	}
	//判断是否是continue
	if analysis.IsContinue(codeLine) {
		return Continue
	}
	//判断是否是break
	if analysis.IsBreak(codeLine) {
		return Break
	}
	if analysis.IsExit(codeLine) {
		return EXIT
	}
	if analysis.IsThrow(codeLine) {
		return Throw
	}

	//判断是否是自增自减
	if analysis.IsIncrementDecrement(codeLine) {
		return IncrementDecrement
	}

	//判断是否是if语句
	if analysis.IsIf(codeLine) {
		return If
	}
	//判断是否是switch语句
	if analysis.IsSwitch(codeLine) {
		return Switch
	}
	//判断是否是for语句
	if analysis.IsFor(codeLine) {
		return For
	}

	//判断是否是to语句
	if analysis.IsTo(codeLine) {
		return To
	}

	//判断是否是变量定义赋值
	if analysis.IsVariableDefine(codeLine) {
		return VariableDefinition
	}
	//判断是否是连续调用赋值
	if analysis.IsUniteCallChainAssignment(threadStore, codeLine) {
		return UniteCallChainAssignment
	}
	//判断是否是连续调用
	if analysis.IsUniteCallChain(threadStore, codeLine) {
		return UniteCallChain
	}
	index1 := func() int {
		//是否是核心函数
		if p := analysis.IsCoreLibFunCall(codeLine); p {
			return CoreFun
		}
		//判断是否是全局文件方法调用
		if analysis.IsGlobalMethodCall(threadStore, codeLine) {
			return GlobalMethod
		}
		//判断是否是this.调用类型方法
		if analysis.IsThisMethodCall(threadStore, codeLine) {
			return ThisMethod
		}
		//判断是否是实例地址调用方法
		if analysis.IsInstanceAddressMethod(threadStore, codeLine) {
			return InstanceAddressMethod
		}

		//判断是否是调用其他文件的方法
		if analysis.IsCrossFileDefineMethodCall(threadStore, codeLine) {
			return CrossFileDefineMethod
		}
		//判断是否是实例方法
		if analysis.IsInstanceMethodCall(threadStore, codeLine) {
			return InstanceMethod
		}

		//判断是多级函数调用
		if analysis.IsMethodCallMulti(threadStore, codeLine) {
			return FunctionCallMulti
		}
		//判断是否是函数调用
		if analysis.IsMethodCall(threadStore, codeLine) {
			return FunctionCall
		}
		return -1
	}()
	if index1 != -1 {
		return index1
	}

	index2 := func() int {
		//判断是否是this.变量=xx赋值
		if analysis.IsThisPropAssign(threadStore, codeLine) {
			return ThisPropAssignment
		}
		//判断是否是global.变量=xx赋值
		if analysis.IsGlobalPropAssignment(threadStore, codeLine) {
			return GlobalPropAssignment
		}

		//判断是否是实例内的属性变量 name=12 (在类的内部,属性)
		if analysis.IsInstanceAttributeAssignment(threadStore, codeLine) {
			return TypeAssignment
		}

		//判断是否是赋值语句(局部)
		if analysis.AssignmentStatement(threadStore, codeLine) {
			return Assignment
		}
		//person.name=12 (在类的外部,获取实例属性)
		if analysis.IsInstancePropAssignment(threadStore, codeLine) {
			return InstancePropAssignment
		}

		return -1
	}()
	if index2 != -1 {
		return index2

	}

	//非关键字代码
	return -1
}

// 只判断是否是函数定义和类型行为定义
func LineAnalysisTypeAndFun(codeLine string) int {
	//判断是否是函数定义
	if analysis.IsFunctionDefine(codeLine) {
		return FunctionDefine
	}
	//判断是否是类型行为定义
	if analysis.IsTypeDefine(codeLine) {
		return TypeDefine
	}
	//判断是否是类型行为定义
	if analysis.IsTypeFunctionDefine(codeLine) {
		return DEF
	}
	return -1
}

// 只判断是否函数调用
func LineAnalysisFunCall(threadStore *structdef.ThreadStore, codeLine string) int {
	//是否是核心函数
	if p := analysis.IsCoreLibFunCall(codeLine); p {
		return CoreFun
	}
	//判断是否是全局文件方法调用
	if analysis.IsGlobalMethodCall(threadStore, codeLine) {
		return GlobalMethod
	}
	//判断是否是this.调用类型方法
	if analysis.IsThisMethodCall(threadStore, codeLine) {
		return ThisMethod
	}
	//判断是否是实例地址调用方法
	if analysis.IsInstanceAddressMethod(threadStore, codeLine) {
		return InstanceAddressMethod
	}

	//判断是否是调用其他文件的方法
	if analysis.IsCrossFileDefineMethodCall(threadStore, codeLine) {
		return CrossFileDefineMethod
	}
	//判断是否是实例方法
	if analysis.IsInstanceMethodCall(threadStore, codeLine) {
		return InstanceMethod
	}
	//判断是否是多级函数调用
	if analysis.IsMethodCallMulti(threadStore, codeLine) {
		return FunctionCallMulti
	}
	//判断是否是函数调用
	if analysis.IsMethodCall(threadStore, codeLine) {
		return FunctionCall
	}
	return -1
}

// 只判断命令行级可执行代码
func CmdLineAnalysis(threadStore *structdef.ThreadStore, codeLine string) int {

	if analysis.IsExit(codeLine) {
		return EXIT
	}
	//判断是否是自增自减
	if analysis.IsIncrementDecrement(codeLine) {
		return IncrementDecrement
	}
	//判断是否是函数调用
	if analysis.IsMethodCall(threadStore, codeLine) {
		return FunctionCall
	}
	//判断是否是实例地址调用方法
	if analysis.IsInstanceAddressMethod(threadStore, codeLine) {
		return InstanceAddressMethod
	}
	//判断是否是调用其他文件的方法
	if analysis.IsCrossFileDefineMethodCall(threadStore, codeLine) {
		return CrossFileDefineMethod
	}
	//判断是否是实例方法
	if analysis.IsInstanceMethodCall(threadStore, codeLine) {
		return InstanceMethod
	}
	//判断是否是变量定义赋值
	if analysis.IsVariableDefine(codeLine) {
		return VariableDefinition
	}
	//判断是否是赋值语句
	if analysis.AssignmentStatement(threadStore, codeLine) {
		return Assignment
	}
	return -1

}
